package com.xr.core.system.service.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.xr.core.system.common.base.MyServiceImpl;
import com.xr.core.system.entity.roleModule.AssignmentPermissionDTO;
import com.xr.core.system.entity.roleModule.Role;
import com.xr.core.system.mapper.RoleMapper;
import com.xr.core.system.service.RoleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 角色表(Role)表服务实现类
 */
@Service("roleService")
public class RoleServiceImpl extends MyServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    /**
     * 给角色分配权限
     *
     * @param assignmentPermissionDTO
     * @return
     */
    @Override
    public boolean assignmentPermissionForRole(AssignmentPermissionDTO assignmentPermissionDTO) {
        List<Long> checkList = assignmentPermissionDTO.getCheckList();
        List<Long> halfList = assignmentPermissionDTO.getHalfList();
        Long id = assignmentPermissionDTO.getId();
        // 将半选和全选封装到一起
        List<Map<String, Object>> dataList = new LinkedList<>();
        checkList.forEach(ele -> {
            Map<String, Object> dataMap = new HashMap<>(3);
            dataMap.put("permissionId", ele);
            dataMap.put("roleId", id);
            dataMap.put("checked", true);
            dataList.add(dataMap);
        });
        halfList.forEach(ele -> {
            Map<String, Object> dataMap = new HashMap<>(3);
            dataMap.put("permissionId", ele);
            dataMap.put("roleId", id);
            dataMap.put("checked", false);//表示半选
            dataList.add(dataMap);
        });
        // 移除当前角色已选权限
        baseMapper.removeRolePermissionForRole(id);
        boolean res = SqlHelper.retBool(baseMapper.assignmentPermissionForRole(dataList));
        if (res) {
            // 去除角色的已有权限
            LambdaQueryWrapper<Role> query = Wrappers.lambdaQuery();
            query.eq(Role::getId, id);
            Role backRole = roleMapper.selectOne(query);
            SaSession session = SaSessionCustomUtil.getSessionById("role-" + backRole.getCode(), false);
            if (null != session) {
                session.delete("Permission_List");
            }
        }
        // 给指定角色分配权限
        return res;
    }

    /**
     * 获取当前角色已选的权限
     *
     * @param id 角色id
     * @return
     */
    @Override
    public List<Long> listCheckedPermissionForRole(Long id) {
        return baseMapper.listCheckedPermissionForRole(id);
    }

    /**
     * 获取用户关联的角色
     *
     * @param id 账户id
     * @return
     */
    @Override
    public List<Long> getRoleByUserId(Long id) {
        return baseMapper.getRoleByUserId(id);
    }

    /**
     * 新增数据
     *
     * @param role
     * @return
     */
    @Override
    public boolean insert(Role role) {
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Role::getCode, role.getCode());
        Role exist = baseMapper.selectOne(queryWrapper);
        Assert.isNull(exist, "code已存在");
        role.setEnable(true);
        role.setInitial(false);
        return SqlHelper.retBool(baseMapper.insert(role));
    }

    /**
     * 修改数据
     *
     * @param role
     * @return
     */
    @Override
    public boolean update(Role role) {
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Role::getCode, role.getCode()).ne(Role::getId, role.getId());
        Role exist = baseMapper.selectOne(queryWrapper);
        Assert.isNull(exist, "code已存在");
        return SqlHelper.retBool(baseMapper.updateById(role));
    }

    /**
     * 批量设置内置角色
     *
     * @param idList 角色id集合
     * @return
     */
    @Override
    public boolean setInitRole(List<Long> idList) {
        if (idList.size() > 0) {
            // 去除所有内置角色
            LambdaUpdateWrapper<Role> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.eq(Role::getInitial, true).set(Role::getInitial, false);
            Role entity = new Role();
            baseMapper.update(entity, updateWrapper);
            // 重新分配内置角色
            LambdaUpdateWrapper<Role> updateInitWrapper = Wrappers.lambdaUpdate();
            updateInitWrapper.in(Role::getId, idList).set(Role::getInitial, true);
            return SqlHelper.retBool(baseMapper.update(entity, updateInitWrapper));
        }
        return false;
    }

    /**
     * 批量设置默认角色
     *
     * @param idList 角色id集合
     * @return
     */
    @Override
    public boolean setDefaultRole(List<Long> idList) {
        if (idList.size() > 0) {
            // 去除所有默认角色
            LambdaUpdateWrapper<Role> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.eq(Role::getDef, true).set(Role::getDef, false);
            Role entity = new Role();
            baseMapper.update(entity, updateWrapper);
            // 重新分配默认角色
            LambdaUpdateWrapper<Role> updateInitWrapper = Wrappers.lambdaUpdate();
            updateInitWrapper.in(Role::getId, idList).set(Role::getDef, true);
            return SqlHelper.retBool(baseMapper.update(entity, updateInitWrapper));
        }
        return false;
    }

    /**
     * 获取全部默认角色id
     *
     * @return
     */
    @Override
    public List<Object> listDefaultRole() {
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Role::getDef, true).eq(Role::getEnable, true);
        queryWrapper.select(Role::getId);
        return listObjs(queryWrapper);
    }

    /**
     * 通过角色code查询角色的所有权限
     *
     * @param code 角色code
     * @return 权限code
     */
    @Override
    public List<String> permissionCodeByRoleCode(String code) {
        return baseMapper.permissionCodeByRoleCode(code);
    }

}

